package com.smartthinking.destinomusical.camara;

import java.util.List;

import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.Display;

class CameraPreviewFroyo implements CameraPreviewProvider {

	public Camera openCamera(int cameraId) {
		return Camera.open(cameraId);
	}
	
	public void startPreview(Camera camera, int previewWidth, int previewHeight, Display display) {
		Camera.Parameters parameters = camera.getParameters();
		List<Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes();
		Size optimalPreviewSize = CameraPreviewFroyo.getOptimalPreviewSize(supportedPreviewSizes, previewWidth, previewHeight);
		Log.d("CameraPreviewLog", "Optimal Size:" + optimalPreviewSize.width + ", " + optimalPreviewSize.height);
		if (optimalPreviewSize != null) {
			parameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height);
			camera.setParameters(parameters);
			camera.startPreview();
		}
	}

	static Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
	    final double ASPECT_TOLERANCE = 0.1;
	    final double MAX_DOWNSIZE = 1.5;
	    
	    double targetRatio = (double) w / h;
	    if (sizes == null) return null;
	
	    Size optimalSize = null;
	    double minDiff = Double.MAX_VALUE;
	
	    int targetHeight = h;
	
	    // Try to find an size match aspect ratio and size
	    for (Size size : sizes) {
	        double ratio = (double) size.width / size.height;
	        double downsize = (double) size.width / w;
	        if (downsize > MAX_DOWNSIZE) {
	        	//if the preview is a lot larger than our display surface ignore it
	        	//reason - on some phones there is not enough heap available to show the larger preview sizes 
	        	continue;
	        }
	        if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
	        if (Math.abs(size.height - targetHeight) < minDiff) {
	            optimalSize = size;
	            minDiff = Math.abs(size.height - targetHeight);
	        }
	    }
	    
	    // Cannot find the one match the aspect ratio, ignore the requirement
	    //keep the max_downsize requirement
	    if (optimalSize == null) {
	        minDiff = Double.MAX_VALUE;
	        for (Size size : sizes) {
	        	double downsize = (double) size.width / w;
		        if (downsize > MAX_DOWNSIZE) {
		        	continue;
		        }
	            if (Math.abs(size.height - targetHeight) < minDiff) {
	                optimalSize = size;
	                minDiff = Math.abs(size.height - targetHeight);
	            }
	        }
	    }
	    //everything else failed, just take the closest match
	    if (optimalSize == null) {
	        minDiff = Double.MAX_VALUE;
	        for (Size size : sizes) {
	            if (Math.abs(size.height - targetHeight) < minDiff) {
	                optimalSize = size;
	                minDiff = Math.abs(size.height - targetHeight);
	            }
	        }
	    }
	    
	    return optimalSize;
	}
	
}
